#include "./flash.h"
#include "../device/device.h"
#include "./log_uart.h"

namespace driver {

namespace flash {

bool erase(uint32_t addr, uint32_t size) {
    FlashIAP_RegUnLock();
    FlashIAP_Enable();
    FlashIap_CloseAll_WPROT();

    bool ret = false;
    uint32_t index = 0;
    for (; index < size;) {
        ret = SUCCESS == IAP_PageErase(addr + index);
       // logUart->printf("erase:%d => %d", addr + index, ret);
        if (!ret) {
            break;
        }
        index += PageSize;
    }

    FlashIAP_RegLock();
    FlashIAP_Disable();
    FlashIap_OpenAll_WPROT();

    return ret;
}

// 20
// 0, 5
// 0~3, 4~7, 8~11, 12~15, 16~19, 20~23
bool write(uint32_t addr, const void *buf, uint32_t size) {

    FlashIAP_RegUnLock();
    FlashIAP_Enable();
    FlashIap_CloseAll_WPROT();

    bool ret = false;
    const uint32_t *p = reinterpret_cast<const uint32_t *>(buf);
    uint32_t len = (size + 3) / 4;
    for (uint32_t i = 0; i < len; i ++) {
        ret = SUCCESS == IAP_WordProgram(addr, p[i]);
       // logUart->printf("write:%d %d", addr, ret);
        if (!ret) {
            break;
        }
        addr += 4;
    }

    FlashIAP_RegLock();
    FlashIAP_Disable();
    FlashIap_OpenAll_WPROT();
    return ret;
}

void read(uint32_t addr, void *buf, uint32_t size) {
    const uint32_t *pAddr = reinterpret_cast<const uint32_t *>(addr);
    uint32_t len = (size + 3) / 4;
    uint32_t *p = reinterpret_cast<uint32_t *>(buf);
    for (uint32_t i = 0; i < len; i ++) {
        p[i] = pAddr[i];
    }
}

}

}

